import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
import { store } from "../redux/store";

axios.defaults.baseURL = process.env.REACT_APP_BASE_API;
axios.defaults.timeout = 10000;

// Add a request interceptor
axios.interceptors.request.use(
  (config): AxiosRequestConfig<any> => {
    store.dispatch({
      type: "change_Loading",
      payload: true,
    });
    const token = window.localStorage.getItem("token");
    if (token) {
      //@ts-ignore
      config.headers.authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return error;
  }
);

// Add a response interceptor
axios.interceptors.response.use(
  (res) => {
    store.dispatch({
      type: "change_Loading",
      payload: false,
    });
    return res;
  },
  (err) => {
    store.dispatch({
      type: "change_Loading",
      payload: false,
    });
    return Promise.reject(err);
  }
);

// interface ResType<T> {
//   code: number;
//   data?: T;
//   msg: string;
//   err?: string;
// }
interface Http {
  get<T>(url: string, params?: unknown): Promise<AxiosResponse<T>>;
  post<T>(url: string, params?: unknown): Promise<AxiosResponse<T>>;
  put<T>(url: string, params?: unknown): Promise<AxiosResponse<T>>;
  patch<T>(url: string, params?: unknown): Promise<AxiosResponse<T>>;
  delete<T>(url: string, params?: unknown): Promise<AxiosResponse<T>>;
  upload<T>(url: string, params: unknown): Promise<AxiosResponse<T>>;
  download(url: string): void;
}

const http: Http = {
  get(url, params) {
    return new Promise((resolve, reject) => {
      axios
        .get(url, { params })
        .then((res) => {
          resolve(res.data);
        })
        .catch((err) => {
          reject(err);
        });
    });
  },
  post(url, params) {
    return new Promise((resolve, reject) => {
      axios
        .post(url, params)
        .then((res) => {
          resolve(res);
        })
        .catch((err) => {
          reject(err);
        });
    });
  },
  put(url, params) {
    return new Promise((resolve, reject) => {
      axios
        .put(url, params)
        .then((res) => {
          resolve(res);
        })
        .catch((err) => {
          reject(err);
        });
    });
  },
  patch(url, params) {
    return new Promise((resolve, reject) => {
      axios
        .patch(url, params)
        .then((res) => {
          resolve(res);
        })
        .catch((err) => {
          reject(err);
        });
    });
  },
  delete(url, data) {
    return new Promise((resolve, reject) => {
      axios
        .delete(url, { data })
        .then((res) => {
          resolve(res);
        })
        .catch((err) => {
          reject(err);
        });
    });
  },
  upload(url, file) {
    return new Promise((resolve, reject) => {
      axios
        .post(url, file, {
          headers: { "Content-Type": "multipart/form-data" },
        })
        .then((res) => {
          resolve(res.data);
        })
        .catch((err) => {
          reject(err);
        });
    });
  },
  download(url) {
    const iframe = document.createElement("iframe");
    iframe.style.display = "none";
    iframe.src = url;
    iframe.onload = function () {
      document.body.removeChild(iframe);
    };
    document.body.appendChild(iframe);
  },
};
export default http;
